home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
d86v311b.arc
/
BIOS.8
< prev
next >
Wrap
Text File
|
1987-11-23
|
37KB
|
901 lines
;---------------
; BIOS module for the D86 debugger
;---------------
; Copyright (C)1987 Eric Isaacson. All rights reserved. Permission to
; copy and use this module is granted ONLY for machines registered for both
; the A86 assembler and the D86 debugger.
; Current support: IBM-PC, Wang PC, TI-PC, Sanyo 555, and Tandy 2000
; This module defines the BIOS interface for my D86 debugger. I am publishing
; it to assist those who wish to assist me in implementing D86 on machines not
; BIOS-compatible with the IBM-PC. To support a non-standard BIOS, we must
; provide new keyboard codes, new action routines, and several other data
; quantities. The scenario for this is as follows:
; First, the debugger calls the procedure SET_MACHINE. This procedure must
; detect what kind of machine it is running on, and set two variables:
;
; * SUBDIR_CHAR, a byte giving the character that indicates a subdirectory for
; an MS-DOS path name on your computer. On an IBM-PC this is a backslash \
; (e.g. a file name can be \usr\eric\foo.com); on a Wang this is an ordinary
; backslash (e.g. the same file is /usr/eric/foo.com).
;
; * BIOS_INIT, a pointer to a procedure that does BIOS-specific
; initializations.
;
; Next, after performing some internal initializations, the debugger calls the
; BIOS_INIT routine. That routine must do three things:
;
; 1. The routine must point SI to a special data structure (which I'll
; describe shortly), then call the routine NEW_KEYS, to propagate the
; items in the structure to the necessary places throughout the debugger.
;
; 2. The routine must perform any initializations necessary for this BIOS.
; For example, WANG_CONFIG locates and stores the port number for hardware
; that enables video access on the Wang.
;
; 3. The routine must decide if the debugger is running on the same screen as
; the user program. If it is, it must move the user's cursor to the lower
; left corner of the screen.
;
; The structure fed to NEW_KEYS contains all the data necessary for ongoing
; debugger execution under the new BIOS. See the structure WANG_KEYS for a
; prototype. The structure consists of the following:
;
; * a byte giving the keyboard code for the debugger's HELP key.
;
; * a byte declaring the difference between your BIOS's key codes for
; function keys, and the IBM BIOS's key codes. Your BIOS_KEY must return
; consecutive values for the function keys F1 through F10. You should
; declare this byte to be X - FUNC, where X is one less than the code
; returned by the F1 key. For example, since the Wang F1 key returns hex
; 080, the byte is declared 07F - FUNC.
; * a number of bytes giving code values for all the other control keys
; used by the debugger. This list will be expanding with new versions;
; see WANG_KEYS for the current version's list. You should precede the list
; with the L1 label, and follow it with the declaration N_CONTROL_KEYS EQU
; $-L1, exactly as shown. Don't change the name N_CONTROL_KEYS; the
; redeclaration of the same name insures that you've gotten the right number
; of codes into the table.
;
; * a word pointing to a message string with the name of the help-key. If your
; keyboard has a key labelled HELP, use the name HELP_HELP as in WANG_KEYS.
; If there is another key nonexistent on the IBM-PC (e.g. F11), then put
; a new name (e.g. F11_HELP) following DW; I'll supply the definition for
; the new name. If there is no extra key and no HELP key, use Alt-F10 as
; on the IBM-PC, and declare DW ALTF10_HELP here.
;
; * the label L2: to be used to verify the number of following bytes.
;
; * pointers to your BIOS's versions of the procedures VID_COPY, VID_ATTR,
; VID_FIX, BIOS_BELL, and BIOS_KEY, described shortly. Substitute the name
; of your machine for VID and BIOS in the generic names; e.g. the WANG_KEYS
; structure has WANG_COPY, WANG_ATTR, WANG_BELL, and WANG_KEY.
;
; * a word giving the segment register value for video memory on your machine.
; The debugger will supply this value in the ES register when it calls
; VID_COPY and VID_ATTR. That is all the debugger does with it; so this
; value can really be anything that the BIOS's versions of VID_COPY and
; VID_ATTR want.
;
; * a byte giving the attribute value for normal video. This attribute will
; be in effect for the entire debugger screen, except for the location of
; the debugger's cursor.
;
; * a byte giving the attribute value for reverse video. This attribute will
; be used to mark the debugger cursor.
;
; * the declaration N_BIOS_CALLS EQU ($-L2)/2 Again, don't change the name;
; the redeclaration of the name insures you didn't leave anything out.
;
; This completes the description of the structure fed to NEW_KEYS. After
; BIOS_INIT is called, the debugger will keep calling 7 action routines to
; perform its interactive I/O. The routines must perform actions as
; follows:
; VID_COPY copies CL bytes of characters from DS:SI to the video memory whose
; location is given by ES:DI. The characters should have the attribute
; NORM_ATTR, which the caller will place into AH for VID_COPY's convenience.
; VID_COPY must place the character byte and the attribute byte into each
; output video word. VID_COPY must return with BL preserved, the high byte
; of SI preserved (it will be if you leave SI pointing beyond the bytes
; copied), and DI advanced beyond the video memory just output. The caller
; assumes that video memory can be found at the value of VIDEO_SEG set by
; BIOS_INIT, starting at offset 0, and proceeding consecutively, one 16-bit
; memory word for every character. The caller will set CH=0 for its first
; call, so that VID_COPY can use CX as the count; but if it does, it must
; return CH=0 for subsequent calls.
; VID_ATTR places the attribute byte AL into the video word whose location is
; given by ES:DI. The character byte of the video word must not be disturbed.
; VID_FIX restores a video screen that might have been clobbered by programs
; external to the debugger. If VID_COPY copies all characters to video memory
; every time, then VID_FIX should RET without doing anything. If, however,
; VID_COPY tries to keep track of which characters are already on the screen,
; and suppress video output for those that are, then VID_FIX should disable
; the suppression feature, call the debugger's routine REFRESH to update the
; whole screen, then re-enable the suppression feature.
; BIOS_BELL rings the bell. NOTE that it is not acceptible for BIOS_BELL to
; use the MS-DOS write routine to send a bell control-code to standard output;
; if it did, then the debugger couldn't debug programs that have redirected
; their standard output-- the bell code would go to the user program's output
; file, and not be translated into a beep.
; BIOS_KEY returns in AL a code for a single keystroke. The code should be
; compatible with the values placed into the debugger's function tables by
; BIOS_INIT. If there is no keystroke available, BIOS_KEY should wait until
; there is one. BIOS_KEY should return on each individual key, and not wait
; for any line-editing to take place.
; BIOS_SAVE saves whatever there is about the user program's BIOS state that
; might be clobbered by the debugger. Currently, the only such thing is
; the user's cursor position on the Sanyo. So on all machines but the Sanyo,
; this is a "do-nothing" routine.
; BIOS_RESTORE restores the BIOS state saved by BIOS_SAVE. Again, this routine
; does nothing except on the Sanyo, on which it restores the user cursor
; position, clobbered because D86 must use BIOS calls to write to the Sanyo
; screen.
; SET_MACHINE determines what kind of machine we are running on, and sets
; the variables SUBDIR_CHAR and BIOS_INIT accordingly.
TI_MSG_PTR DD 0F400:0A022
TI_MSG:
DB 'Texas I'
TI_MSG_LEN EQU $-TI_MSG
TANDY_MSG1_PTR DD 0FC00:0002F ; There are two BIOS versions for
TANDY_MSG2_PTR EQU 0032 ; the Tandy 2000 slightly different
TANDY_MSG:
DB 'Tandy'
TANDY_MSG_LEN EQU $-TANDY_MSG
L2: ; BH is not 1
ADD BH,2 ; was BH 0FF?
JNZ RET ; return if not -- we are on an IBM-PC
MOV ES,AX,0FFFF ; it was-- address the end of ROM
ES CMP AX,[6] ; are there FFFF's beyond the boot-JMP?
MOV AX,SANYO_CONFIG ; load Sanyo address, in case there were
JE >L1 ; jump if there were-- it is a Sanyo
RET
SET_MACHINE:
CMP DH,DH ; set Z so a JMP can be patched into NOPS
NOP ; you could patch a JMP to force a specific interface
NOP
LES DI,TI_MSG_PTR ; point to the identifying message in the TI-PC ROM
MOV SI,TI_MSG ; point to our copy of that message
MOV CX,TI_MSG_LEN ; load the number of bytes that we have
REPE CMPSB ; is the message there in ROM?
MOV AX,TIPC_CONFIG ; load pointer to TI-PC's BIOS_INIT in case it is
JE >L1 ; jump if it is, to store the pointer
LES DI,TANDY_MSG1_PTR ; point to the identifying message in the T2K ROM
MOV SI,TANDY_MSG ; point to Tandy identifying message
MOV CX,TANDY_MSG_LEN ; length of message to compare
PUSH SI,CX ; save pointer+count in case we have to try other place
REPE CMPSB ; check for match in ROM header
POP CX,SI ; restore count and pointer
MOV AX,TANDY_CONFIG ; set pointer to Tandy 2000 BIOS_INIT
JE >L1 ; jump and store pointer if we found it
MOV DI,TANDY_MSG2_PTR ; point to second version message in the T2K ROM
REPE CMPSB ; check for match in ROM header
JE >L1 ; jump and store pointer if we found it
MOV AH,030 ; MS-DOS function number for VERSION
INT 33 ; fetch the version; we want the machine code BH
DEC BH ; if BH was 1 we are on a Wang PC
JNZ L2 ; variables already set if we are on an IBM-PC
MOV SUBDIR_CHAR,'/' ; subdirectory character on a Wang is /
MOV AX,WANG_CONFIG ; action routine for TI-PC is TIPC_CONFIG
L1:
MOV BIOS_INIT,AX ; store the action routine for this machine
RET
; IBM_CONFIG is the BIOS_INIT routine for the IBM-PC. Since its NEW_KEY
; values are the defaults, we do not need to call NEW_KEY.
IBM_CONFIG:
MOV AH,15 ; function number for GET_VIDEO_MODE
INT 16 ; call the BIOS to get the mode
CMP AL,7 ; are we in monochrome mode?
MOV AX,0B000 ; load monochrome map location in case yes
IF B MOV AH,0B8 ; if not then load color map location
MOV BL,V_FLAG ; load the setting of the -V switch
XOR AH,BL ; switch intefaces if we saw a -V in invocation
CS MOV VIDEO_SEG,AX ; store the location of physical video
TEST AH,8 ; are we on a CGA video board?
JZ >L1 ; skip if not
CS MOV VID_COPY,COLOR_COPY ; we are: change the video-copy routine
CS MOV BIOS_RESTORE,COLOR_RESTORE
CS MOV REV_ATTR,0F0 ; change the reverse-video to blinking
L1:
TEST BL ; are we the same screen as the user program?
JNZ RET ; return if we are not-- no need to move cursor
SET_IBM_LOW_LEFT:
MOV BH,0 ; page number is zero
MOV DX,24 BY 0 ; we will move the cursor to row 24, column 0
SET_IBM_CURSOR:
MOV AH,2 ; video BIOS function number for SET CURSOR POSITION
INT 16 ; call the BIOS to put user cursor in lower left corner
RET
; IBM_FIX performs a fixup of a trashed screen on an IBM machine.
; COLOR_RESTORE checks to see if the debugger screen has been trashed. If it
; has, we restore the screen.
COLOR_RESTORE:
PUSH DS
MOV DS,AX,0B800
MOV DX,03DA ; load the port number for reading the video status
L2: ; loop here to wait for vertical retrace
IN AL,DX ; input the status
TEST AL,1 ; mask the retrace bit
JZ L2 ; loop if we are not in vertical retrace
CMP B[2400],'A'
POP DS
JE RET
IBM_FIX:
CS PUSH VID_COPY ; save the old VID_COPY value
CS MOV VID_COPY,MONO_COPY ; coerce it to MONO_COPY, to blindly copy all
CALL REFRESH ; refresh the screen; let the snow scatter!
CS POP VID_COPY ; restore the old VID_COPY value
IBM_SAVE:
IBM_RESTORE:
RET
; MONO_COPY is the VID_COPY routine for an IBM monochrome video board. The
; characters occupy the lower byte of the DI-pointed words. We can afford
; to rewrite the entire screen on each refresh; so no special action needs to
; be taken. We do complicated looping to make the routine as fast as
; possible.
MONO_COPY:
SHR CX,1 ; is the character count odd?
JC >L5 ; jump if yes, to special code
L1:
SHR CX,1 ; is the character count a multiple of 4?
JC >L6 ; jump if not, to special code
L2: ; loop here to copy every 4 bytes
LODSB ; load the character from the source
STOSW ; output the character, with the standard attribute byte
LODSB ; char # 2
STOSW
LODSB ; char # 3
STOSW
LODSB ; char # 4
STOSW
LOOP L2 ; loop for the next 4 characters
RET
L5: ; the character count was odd
MOVSB ; copy the odd character to the video buffer
INC DI ; advance beyond the attribute byte
JCXZ RET ; return if count is depleted
JMP L1 ; join even code
L6: ; the character count is 2 mod 4
LODSB ; load one character
STOSW ; output it and the attribute-- count now 1 mod 4
LODSB ; load second character
STOSW ; output it-- count now 0 mod 4
JCXZ RET ; return if count is depleted
JMP L2 ; join multiple-of-4 code
; COLOR_COPY is the VID_COPY routine for an IBM Color Graphics Adapter board.
; The characters occupy the lower byte of the DI-pointed words. We must wait
; for vertical retrace to output our data, to avoid annying "snow" on the
; screen. So we can't afford to output the entire buffer every time. So we
; maintain at [SI+81] a copy of what's already on the screen for [SI], and we
; output only if the buffer is new.
COLOR_COPY:
PUSH BX ; preserve BX across the call
MOV DX,03DA ; load the port number for reading the video status
SKIP2 ; skip to the LODSB instruction
L0: ; loop here for every character that is already out there
INC DI ; advance the output pointer beyond the character
L1: ; loop here after a non-matching character was stored
INC DI ; advance beyond the following attribute byte
LODSB ; fetch the next character
MOV BL,AL ; save the character in BL
XCHG AL,[SI+79] ; swap it with the already-out-there value
CMP AL,BL ; is the character already out there?
LOOPE L0 ; loop if it is
JE >L4 ; jump if the characters are exhausted
L2: ; loop here to wait for vertical retrace
IN AL,DX ; input the status
TEST AL,1 ; mask the retrace bit
JZ L2 ; loop if we are not in vertical retrace
MOV AL,BL ; re-fetch the character to be output
STOSB ; output the character
INC CX ; undo the previous LOOPE's decrement of CX
LOOP L1 ; loop to check for another output character
INC DI ; advance beyond the attribute byte of the last character
POP BX ; restore clobbered register
RET
L4: ; matching character was the last in the buffer
INC DI,2 ; advance beyond the output video word
POP BX ; restore clobbered register
RET
; IBM_ATTR is the VID_ATTR routine for IBM-PC compatible computers. The
; attribute byte is the high byte of the DI-pointed video word.
IBM_ATTR:
INC DI ; advance to the high, attribute byte
STOSB ; output the attribute code AL to the byte
RET
; IBM_KEY is the BIOS_KEY routine for IBM_PC compatible computers. We must
; transform the two-byte code returned by the IBM BIOS into the single
; code AL expected by the rest of the debugger.
IBM_KEY:
MOV AH,0 ; function code for GET KEY
INT 016 ; get the keystroke from the IBM BIOS
TEST AL ; is the return AL nonzero?
JNZ RET ; if yes then AL is our return code
MOV AL,AH ; AL is zero, so AH determines the return code
ADD AL,080-16 ; shift the values into a range not seen directly in AL
RET
; IBM_BELL is the BIOS_BELL routine for IBM-PC compatible computers. We
; output the code 07 to the BIOS's console output routine.
IBM_BELL:
MOV AX,0E07 ; AH= console out function number; AL="BELL" control code
INT 010 ; output BELL to the console
RET
; NEW_KEYS reassigns the keyboard codes and the action routines for a non-
; IBM-compatible BIOS. We are called with CS:SI pointing to a table of
; various new values, whose format is identical to the one given by
; WANG_KEYS below. The new values are plugged into the various tables
; in the debugger, so that correct actions are taken for the non-compatible
; machine.
NEW_KEYS:
PUSH DS ; preserve DS across call
MOV DS,CS ; point DS to our program, to read the table at SI
MOV ES,CS ; also point the destination segment to our program
LODSB ; load the first byte of the table
MOV HELP_KEY,AL ; first byte is the code for HELP_KEY
LODSB ; load the second byte
ADD SWITCH_KEY,AL ; byte 2 is (new-IBM) function-key-codes-difference
MOV DI,CTRL_JUMPS+2 ; point to the control-jumps table
MOV CX,N_FUNCS ; load the number of function-keys in that table
L1: ; loop here to adjust each function-key code
ADD [DI],AL ; add the code into the table entry
ADD DI,3 ; advance to the next table entry
LOOP L1 ; loop to adjust the next table entry
MOV CL,N_CONTROL_KEYS ; load the number of subsequent keys in the table
L2: ; loop here to plug in the new value for each key
MOVSB ; copy the new key code to the function table
INC DI,2 ; advance output pointer to the next key code
LOOP L2 ; loop to plug in the next key code
LODSW ; fetch the message-pointer to the name of HELP key
MOV HELP_MSG,AX ; plug the pointer into the messages-string
MOV DI,BIOS_CALLS ; point to the table of action routines
MOV CX,N_BIOS_CALLS ; load the count of words in action-routine-table
REP MOVSW ; copy the new pointers to the table
POP DS ; restore clobbered register
RET
;------------------
; WANG INTERFACE
;------------------
; Thanks to Alan Tschetter for providing the information necessary for me
; to program this interface.
WANG_KEYS:
DB 0E1 ; HELP key value
DB 07F-FUNC ; add-quantity for FUNC
L1:
DB 0C2,0C9,0C0,0C8,0C4 ; DOWN, NEXT, UP, PREV, HOME
DB 097,097 ; shift-F7 key, disabled Alt-F9 key
N_CONTROL_KEYS EQU $-L1
DW HELP_HELP ; pointer to "HELP" message, the name of Wang's HELP key
L2:
DW WANG_COPY ; VID_COPY routine
DW WANG_ATTR ; VID_ATTR routine
DW RET ; there is no VID_FIX necessary on the Wang
DW WANG_BELL ; BIOS_BELL routine
DW WANG_KEY ; BIOS_KEY routine
DW RET
DW RET
DW 0F000 ; new value for VIDEO_SEG
DB 0 ; normal-video attribute for the Wang PC
DB 2 ; reverse-video attribute for the Wang PC
N_BIOS_CALLS EQU ($-L2)/2
; Other Wang keycodes: F1--F16 80--8F
; Prev C8 Erase CB
; Insert C6 Delete C7
; <--- C3 ---> C1
; EXEC C5
; All the above codes add 010 for SHIFT versions.
; NO ALT KEY!!!
; Print E3 Back Tab CD
; Cancel E0 Shift Cancel 03
; WANG_CONFIG is the BIOS initialization routine for a Wang PC. We copy the
; values of WANG_KEYS to various locations, then we fetch the value of
; ENABLE_PORT, that lets us access Wang's video memory, then we move the
; user's cursor to the lower left corner.
L1: ; console codes to move cursor to lower left corner
DB 01B,'[25;1H' ; row 25, column 1
L2 EQU $-L1 ; L2 is the count of bytes
WANG_CONFIG:
MOV SI,WANG_KEYS ; point to Wang's table of key codes and other values
CALL NEW_KEYS ; plug the new values into our program's data structures
MOV AL,1 ; function code for GET BIOS ENVIRONMENT
INT 088 ; sets ES to a segment where we'll find port #
ES MOV BX,[BX+10] ; fetch a pointer
ES MOV AH,[BX+19] ; use the pointer to fetch the high of the port #
MOV AL,010 ; low of the port # is always 010
MOV ENABLE_PORT,AX ; store the port number
MOV DS,CS ; point DS to our program, for console sequence
MOV DX,L1 ; point DX to the "go to lower left" console sequence
MOV CX,L2 ; load the number of bytes in the sequence
MOV BH,0 ; device number, maybe? I don't know for sure
MOV AL,0D ; function number, maybe? I don't know for sure
INT 088 ; output escape string, user's cursor goes to lower left
RET
; WANG_COPY is the Wang-PC version of the VID_COPY routine. The character
; and attribute bytes are reversed from what they are on the IBM-PC, so
; AH and AL are swapped before and after every word output. There are no
; snow problems; so we can get away with copying everything every time.
; We do need to enable the video memory, though.
WANG_COPY:
MOV DX,ENABLE_PORT ; fetch the port number for enabling video memory
MOV AL,1 ; value 1 causes memory to be enabled
OUT DX,AL ; we can now access the video memory
L1: ; loop here for each character to be copied
LODSB ; fetch the next character
XCHG AH,AL ; swap character into AH, attribute byte into AL
STOSW ; output the word to video memory
MOV AH,AL ; copy the attribute byte back to AH, for next char
LOOP L1 ; loop to copy the next character
L2: ; common exit with WANG_ATTR
MOV AL,0 ; value 0 shuts off access to video memory
OUT DX,AL ; video access is now disabled
RET
; WANG_ATTR is the Wang-PC version of the VID_ATTR routine. The attribute
; byte is the low byte of the DI-pointed video memory. Also, to access it,
; we must send the code that enables Wang video memory.
WANG_ATTR:
PUSH AX ; preserve the attribute code
MOV DX,ENABLE_PORT ; fetch the port number for enabling video memory
MOV AL,1 ; value 1 causes memory to be enabled
OUT DX,AL ; we can now access the video memory
POP AX ; restore the attribute code
STOSB ; output the attribute byte to the LOW byte of video word
JMP L2 ; join common code to disable video access
; WANG_KEY is the Wang-PC version of the BIOS_KEY routine.
WANG_KEY:
PUSH BX ; preserve register across call
L1: ; loop here to wait for a key to become ready
MOV AL,15 ; Wang BIOS function code for GET KEY STATUS
MOV BL,2 ; another parameter for Wang BIOS - I'm not sure which
INT 088 ; call Wang BIOS to get the status and maybe the key
TEST AL ; do we have a key?
JNZ L1 ; loop if not, to try again
XCHG AX,BX ; we do: swap the key code into AL for return
POP BX ; restore clobbered register
RET
; WANG_BELL is the Wang-PC version of the BIOS_BELL routine.
WANG_BELL:
MOV BX,7 ; BL=7 is the BELL code; the BIOS also wants BH=0
MOV AL,6 ; Wang BIOS function code for CONSOLE OUTPUT
INT 088 ; output the BELL control code to the Wang console
RET
;------------------
; TI-PC INTERFACE
;------------------
; Thanks to David R. Cook for writing the following code. I have reformatted
; it to look like the rest of my code, and made optimizations.
TIPC_KEYS:
DB 0B5 ; key code for F11 - the help key
DB 0AA-FUNC ; F1 is code 0AB on the TI-PC
L1:
DB 0C0 ; down-arrow key
DB 0C1 ; no PgDn key on the TI-PC, so we use alt-down-arrow code
DB 0B8 ; up-arrow key
DB 0B9 ; no PgUp key on the TI-PC, so we use alt-up-arrow code
DB 0B7 ; HOME key
DB 0CA ; shift-F7 key
DB 0E0 ; alt-F9 key
N_CONTROL_KEYS equ $-L1
DW F11_HELP ; pointer to help message
L2:
DW TIPC_COPY ; VID_COPY routine
DW TIPC_ATTR ; VID_ATTR routine
DW TIPC_FIX ; VID_FIX routine
DW TIPC_BELL ; BIOS_BELL routine
DW TIPC_KEY ; BIOS_KEY routine
DW RET
DW RET
DW 0DE00 ; new value for VIDEO_SEG
DB 0F ; normal-video attribute for the TI-PC
DB 01F ; reverse-video attribute for the TI-PC
N_BIOS_CALLS equ ($-L2)/2
; Other TI keycodes:
; key +shift +alt +ctrl plain
; ----------------------------------
; F1 0C4 0D8 0CE 0AB
; ...
; F10 0CD 0E1 0D7 0B4
; F11 "x" "|" "z" 0B5
; F12 "y" "}" "{" 0B6
;
; PRNT 0E2
; INS 098 09A 099 0C2
; DEL 0A8 0AA 0A9 0C3
; UP AR 0F8 0B9 0F4
; DN AR 0F9 0C1 0E6
; LT AR 0FB 0BC 0E3 0BB
; RT AR 0FA 0BE 0E4 0BD
; HOME 0F6 0F5 0E7
; TAB 07F ignored ignored 09
; TIPC_CONFIG is the BIOS initialization routine for the TI-PC. We copy the
; values in TIPC_KEYS to various locations, then we drop into TIPC_FIX,
; to reset the cursor.
TIPC_CONFIG:
MOV SI,TIPC_KEYS ; point to configuration-table for TI-PC's BIOS
CALL NEW_KEYS ; copy the values to our tables
TIPC_FIX:
MOV AH,014 ; BIOS function code for "clear graphics screen"
INT 049 ; clear the graphics screen
MOV AH,013 ; BIOS function code for "clear text screen"
INT 049 ; clear the text screen
MOV AH,2 ; BIOS function code for "position the cursor"
MOV DX,1 BY 24 ; first column, 24th row
INT 049 ; move the user's cursor to the bottom left corner
RET
; TIPC_COPY is the VID_COPY routine for the TIPC video board. The attribute
; AH is written to a single memory-mapped latch in the video segment.
; Then the text bytes can be copied as-is.
TIPC_COPY:
ES MOV B[01801],AH ; set the attribute latch
SHR DI,1 ; adjust the video address for bytes, not words
REP MOVSB ; copy the text as-is
SHL DI,1 ; restore the video address to words, not bytes
RET
; TIPC_ATTR is the VID_ATTR routine for TI-PC computer. We change the
; attribute latch to the one provided in AL, then we add 0 to the video
; character in memory, causing the new latch value to take effect.
TIPC_ATTR:
SHR DI,1 ; adjust video address for bytes, not words
ES MOV AH,B[DI] ; fetch the character
ES MOV B[01801],AL ; rewrite the latch with the caller's value
ES MOV B[DI],AH ; re-write the value already there, to effect the latch
SHL DI,1 ; restore DI
RET
; TIPC_KEY is the BIOS_KEY routine for TI_PC computer. We must transform the
; two-byte code returned by the TIPC BIOS into the single code AL expected by
; the rest of the debugger. The only differences to IBM_KEY are the interrupt
; number, and the mapping of the codes received and returned.
TIPC_KEY:
MOV AH,0 ; function code for GET KEY
INT 04A ; get the keystroke from the TIPC BIOS
TEST AL ; is the return AL nonzero?
JNZ RET ; if yes then AL is our return code
MOV AL,AH ; AL is zero, so AH determines the return code
ADD AL,080-16 ; shift the values into a range not seen directly in AL
RET
; TIPC_BELL is the BIOS_BELL routine for TIPC-PC computer. We output the code
; 07 to the BIOS's console output routine. The only difference to IBM_KEY is
; the interrupt number.
TIPC_BELL:
MOV AX,0E07 ; AH= console out function number; AL="BELL" control code
INT 049 ; output BELL to the console
RET
;------------------
; SANYO INTERFACE
;------------------
; Thanks to Jerry Farnsworth for providing the information necessary for me
; to program this interface.
SANYO_KEYS:
DB 0DC ; key code for Ctrl-PF5 -- the help key
DB 0 ; same function codes as IBM-PC
L1:
DB 0C0 ; down-arrow key
DB 0C1 ; PgDn key
DB 0B8 ; up-arrow key
DB 0B9 ; PgUp key
DB 0B7 ; HOME key
DB 0CA ; shift-F7 key is Ctrl 7 on the Sanyo
DB ALT_F 9 ; Ctrl-Shift-PF4 will restore a trashed screen
N_CONTROL_KEYS equ $-L1
DW PF5_HELP ; pointer to help message
L2:
DW SANYO_COPY ; VID_COPY routine
DW SANYO_ATTR ; VID_ATTR routine
DW SANYO_FIX ; VID_FIX routine
DW IBM_BELL ; BIOS_BELL routine
DW IBM_KEY ; BIOS_KEY routine
DW SANYO_SAVE ; we must save the BIOS cursor position
DW SANYO_RESTORE ; we must restore the BIOS cursor position
DW 07C00 ; new value for VIDEO_SEG
DB 07 ; normal-video attribute for the Sanyo-PC
DB 0F0 ; reverse-video attribute for the Sanyo-PC
N_BIOS_CALLS equ ($-L2)/2
; Other Sanyo keycodes:
; IBM Sanyo IBM Sanyo
; Alt Ctrl Shift DOWN numeric pad 5
; Alt Fn Ctrl Fn END numeric pad 2
; Shift Fn Ctrl n
; Ctrl 2 Ctrl ` Ctrl F12345 Ctrl ={}:"
; Ctrl 6 Ctrl tilde Ctrl F678910 Ctrl ;',./
; SANYO_CONFIG is the BIOS initialization routine for a Sanyo 55x. We copy the
; values of SANYO_KEYS to various locations, fetch and store the current
; video page, and set the user cursor to the lower left of the screen.
; SANYO_FIX insures a screen refresh by filling the "actual" buffers of SCREEN_P
; with impossible FF-values.
SANYO_CONFIG:
MOV SI,SANYO_KEYS ; point to configuration-table for SANYO's BIOS
CALL NEW_KEYS ; copy the values to our tables
MOV AH,15 ; function number for fetching the video page
INT 010 ; set BH to the current video page
CS MOV SANYO_PAGE,BH ; store the page throughout the debugging session
MOV DX,24 BY 0 ; load coordinates for the lower left corner
CALL SET_SANYO_POS ; store this position
CALL SANYO_RESTORE ; this call causes the user cursor to move there
SANYO_FIX:
NO_ACTUAL:
MOV AX,0FFFF ; load AH and AL with the 0FF impossible-value
FILL_ACTUAL:
MOV ES,SS ; destination segment is our stack, for buffer-fill
MOV DI,SCREEN_P+80 ; point to the actual-buffer for the first line
MOV DL,24 ; load the count of actual lines to fill
L2:
MOV CX,40 ; number of words in the actual buffer
REP STOSW ; fill the buffer with the words
ADD DI,256-80 ; advance output pointer to the next line's actual buff.
DEC DL ; count down lines
JNZ L2 ; loop to fill the next line
RET
; SANYO_COPY is the VID_COPY routine for the Sanyo. The Sanyo does not have
; a hardware character generator, so we call the BIOS to copy bit-patterns
; to the screen.
SANYO_COPY:
MOV AX,DI ; fetch the output character number
ADD DI,CX ; add the character count
ADD DI,CX ; add it twice, to advance by words not bytes
PUSH BX,DI ; preserve caller's BX and return DI value
MOV BH,0 ; load the page number
SANYO_PAGE EQU B[$-1] ; previous immediate value is plugged in
CALL GET_ROWCOL ; convert character number AX into row-and-column DX
DEC DX ; cancel the following first INC DX
L1: ; loop here for every character already out there
INC DX ; advance the column number DL to the next position
LODSB ; fetch the next character
MOV BL,AL ; save the character in BL
XCHG AL,[SI+79] ; swap it with the already-out-there value
CMP AL,BL ; is the character already out there?
LOOPE L1 ; loop if it is
JE >L2 ; jump if the characters are exhausted
INC CX ; undo the previous LOOPE's decrement of CX
CALL SET_IBM_CURSOR ; move the cursor to the indicated position
MOV AL,BL ; fetch the character to be output
MOV BL,7 ; load the attribute code, always 7 in Sanyo's case
PUSH CX ; save the character count
MOV CX,1 ; we are outputting 1 character in this call
MOV AH,9 ; BIOS function number for WRITE_CHAR
INT 010 ; write the character to the screen
POP CX ; restore the character count
LOOP L1 ; loop to check for another output character
L2:
POP DI,BX ; restore clobbered registers
RET
; SANYO_ATTR is the VID_ATTR routine for the Sanyo. We use the BIOS to
; move the cursor to the current position, read the character that is
; already there, and rewrite the character with the new attribute.
SANYO_ATTR:
PUSH BX,CX,DX,DI ; save registers across call
PUSH AX ; save the attribute across the repositioning
MOV AX,DI ; fetch the character number
CALL GET_ROWCOL ; convert the character number AX to row-and-column DX
CS MOV BH,SANYO_PAGE ; load the current page number
CALL SET_IBM_CURSOR ; move the cursor to the required location
MOV AH,8 ; function number for READ_CHARACTER
INT 010 ; set AL to the character already there
POP DX ; restore DL = new attribute byte
MOV BL,DL ; copy the attribute to BL where the BIOS expects it
MOV CX,1 ; we are writing one character only
MOV AH,9 ; BIOS function number for WRITE_CHAR
INT 010 ; write the character to the screen
POP DI,DX,CX,BX ; restore clobbered registers
RET
; GET_ROWCOL an address AX into a row number DH and column number DL. The input
; AX address is twice the number of characters from the start of the screen
; to the current cursor position.
GET_ROWCOL:
MOV DI,160 ; each line advances the address by 160
SUB DX,DX ; the upper word of the dividend DXAX is always 0
DIV DI ; convert the address to row AX, column DL*2
MOV DH,AL ; the row is returned in DH
SHR DL,1 ; the column is returned in DL
RET
; SANYO_SAVE is the BIOS_SAVE routine for the Sanyo. We record the user's
; cursor position, so that it can be restored by BIOS_RESTORE.
SANYO_SAVE:
MOV AH,3 ; BIOS function number for READ_CURSOR_POSITION
INT 010 ; set DX to the current user cursor position
SET_SANYO_POS:
CS MOV SANYO_POS,DX ; store the cursor position DX
RET
; SANYO_RESTORE is the BIOS_RESTORE routine for the Sanyo. We set the
; user's sursor position to the place previously stored.
SANYO_RESTORE:
MOV DX,0 ; fetch the cursor position
SANYO_POS EQU W[$-2] ; the above immedaite operand has been plugged
JMP SET_IBM_CURSOR ; jump to set the user's cursor
;------------------------
; TANDY 2000 INTERFACE
;------------------------
; Thanks to John B. Harrell, Contributing Editor PC Resuorce, for writing
; the following code. I have made minor code optimizations.
TANDY_KEYS:
DB ALT_F 10 ; code for Alt-F10 -- the HELP key
DB 0 ; F1 code same as on IBM-PC
L1:
DB 0C0 ; Down Arrow
DB 0C1 ; PgDn
DB 0B8 ; Up Arrow
DB 0B9 ; PgUp
DB 0B7 ; Home
DB 0CA ; Shift F7
DB ALT_F 9 ; Alt-F9 fixes a trashed screen
N_CONTROL_KEYS EQU $-L1
DW ALTF10_HELP ; pointer to help message
L2:
DW MONO_COPY ; VID_COPY routine
DW IBM_ATTR ; VID_ATTR routine
DW TANDY_FIX ; VID_FIX routine
DW IBM_BELL ; BIOS_BELL routine
DW IBM_KEY ; BIOS_KEY routine
DW RET ; BIOS_SAVE routine needed for Sanyo only
DW RET ; BIOS_RESTORE routine needed for Sanyo only
TANDY_VSEG DW ? ; Tandy 2000 floating video segment address = VIDEO_SEG
DB 0A ; normal video attribute on Tandy 2000
DB 0CA ; reverse video attribute on Tandy 2000
N_BIOS_CALLS EQU ($-L2)/2
; Other Tandy 2000 keycodes:
; key +shift +alt +ctrl plain
; ----------------------------------
; F1 0C4 0D8 0CE 0AB
; ...
; F10 0CD 0E1 0D7 0B4
; F11 012 "&" 01C 008
; F12 013 "`" 01D 009
;
; PRNT --- 0B6 0E2 010
; INS 0F9 010 00F 0C2
; DEL 0FA 00E 00D 0C3
; UP AR 0F5 001 000
; DN AR 0F6 007 006
; LT AR 0F7 002 0E3 0BB
; RT AR 0F8 --- 0E4 0BD
; HOME 0BA 016 0E7
; TAB 07F 0FE 0FD 009
; BKSP 008 0FC 07F 008
; TAB 07F 0FE 0FD 009
; ESC 01B 0FB 01B 01B
; END --- --- 0E5 0BF
; PGUP --- --- 0F4 0B9
; PGDN --- --- 0E6
TANDY_CONFIG:
INT 012 ; get reported memory size in KBytes
MOV CL,6 ; shift count = * 64 for Kbytes to paragraphs
SHL AX,CL ; convert to paragraphs
ADD AX,0080 ; point to starting location of monochrome video buffer
CS MOV TANDY_VSEG,AX ; save in data structure
MOV SI,TANDY_KEYS ; point to configuration table for Tandy 2000
CALL NEW_KEYS ; copy the value into BIOS tables
TANDY_FIX:
MOV AX,0 BY 2 ; AH= BIOS function code for SET_VIDEO_MODE; AL = mode 0
INT 16 ; force a monochrome video mode
JMP SET_IBM_LOW_LEFT ; move the cursor to the lower left corner